#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QFileDialog>
#include <QTextStream>
#include <QMessageBox>
#include <QTableWidget>
#include <QTableWidgetItem>
#include <QTextEdit>
#include <QPushButton>
#include <QTextCursor>
#include <QTextCharFormat>
#include <QInputDialog>

// 中断处理器实现类
class MainWindowInterruptHandler : public InterruptHandler {
private:
    MainWindow* mainWindow;
    int handlerType; // 0=加法服务, 1=打印服务
    
public:
    MainWindowInterruptHandler(MainWindow* mw, int type) : mainWindow(mw), handlerType(type) {}
    
    void handleInterrupt(int interruptNumber) override {
        if (handlerType == 0) {
            // 加法服务
            int a = mainWindow->getCpu()->getRegister("AX");
            int b = mainWindow->getCpu()->getRegister("BX");
            mainWindow->getCpu()->setRegister("AX", a + b);
            mainWindow->getOutputTextEdit()->append("中断20: 执行加法服务");
        } else if (handlerType == 1) {
            // 打印服务
            int value = mainWindow->getCpu()->getRegister("AX");
            mainWindow->getOutputTextEdit()->append(QString("中断21: 打印值 - %1").arg(value));
        }
    }
};

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    setWindowTitle("汇编程序解释器");
    
    // 初始化CPU和中断管理器
    interruptManager = new InterruptManager(this);
    cpu = new CPU(interruptManager); // 修复：只传递一个参数
    
    // 设置UI
    setupUI();
    
    // 设置中断处理
    setupInterrupts();
    
    // 初始化状态
    currentInstructionIndex = 0;
}

MainWindow::~MainWindow()
{
    delete ui;
}

// 添加获取CPU和OutputTextEdit的公共方法
CPU* MainWindow::getCpu() const {
    return cpu;
}

QTextEdit* MainWindow::getOutputTextEdit() const {
    return ui->outputTextEdit;
}

void MainWindow::setupUI()
{
    // 初始化代码编辑器
    ui->codeEditor->setFontFamily("Courier New");
    ui->codeEditor->setPlainText("; 汇编代码示例\nMOV AX, $10\nMOV BX, $5\nADD AX, BX\nMOV [100], AX\nINT 21");
    
    // 初始化寄存器显示
    ui->registersTable->setRowCount(10);
    ui->registersTable->setColumnCount(2);
    ui->registersTable->setHorizontalHeaderLabels({"寄存器", "值"});
    QStringList registerNames = {"AX", "BX", "CX", "DX", "SI", "DI", "BP", "SP", "IP", "FLAGS"};
    
    for (int i = 0; i < registerNames.size(); ++i) {
        ui->registersTable->setItem(i, 0, new QTableWidgetItem(registerNames[i]));
        ui->registersTable->setItem(i, 1, new QTableWidgetItem("0"));
    }
    
    // 初始化内存显示
    ui->memoryTable->setRowCount(10);
    ui->memoryTable->setColumnCount(11);
    QStringList memoryHeaders;
    memoryHeaders << "地址";
    for (int i = 0; i < 10; ++i) {
        memoryHeaders << QString::number(i);
    }
    ui->memoryTable->setHorizontalHeaderLabels(memoryHeaders);
    
    for (int i = 0; i < 10; ++i) {
        ui->memoryTable->setItem(i, 0, new QTableWidgetItem(QString::number(i * 10)));
        for (int j = 1; j < 11; ++j) {
            ui->memoryTable->setItem(i, j, new QTableWidgetItem("0"));
        }
    }
    
    // 连接信号和槽
    connect(ui->runButton, &QPushButton::clicked, this, &MainWindow::on_runButton_clicked);
    connect(ui->stepButton, &QPushButton::clicked, this, &MainWindow::on_stepButton_clicked);
    connect(ui->resetButton, &QPushButton::clicked, this, &MainWindow::on_resetButton_clicked);
    connect(ui->interruptButton, &QPushButton::clicked, this, &MainWindow::on_interruptButton_clicked);
    connect(ui->loadExampleButton, &QPushButton::clicked, this, &MainWindow::on_loadExampleButton_clicked);
    connect(ui->saveButton, &QPushButton::clicked, this, &MainWindow::on_saveButton_clicked);
    connect(ui->loadButton, &QPushButton::clicked, this, &MainWindow::on_loadButton_clicked);
}

void MainWindow::setupInterrupts()
{
    // 注册中断处理程序 - 修复：使用InterruptHandler子类
    interruptManager->registerInterruptHandler(20, new MainWindowInterruptHandler(this, 0));
    interruptManager->registerInterruptHandler(21, new MainWindowInterruptHandler(this, 1));
}

void MainWindow::updateRegistersDisplay()
{
    QStringList registerNames = {"AX", "BX", "CX", "DX", "SI", "DI", "BP", "SP", "IP", "FLAGS"};
    
    for (int i = 0; i < registerNames.size(); ++i) {
        ui->registersTable->item(i, 1)->setText(QString::number(cpu->getRegister(registerNames[i])));
    }
}

void MainWindow::updateMemoryDisplay()
{
    for (int i = 0; i < 10; ++i) {
        for (int j = 1; j < 11; ++j) {
            int address = i * 10 + (j - 1);
            ui->memoryTable->item(i, j)->setText(QString::number(cpu->getMemory(address)));
        }
    }
}

void MainWindow::updateCodeDisplay()
{
    QString code = ui->codeEditor->toPlainText();
    QStringList lines = code.split('\n');
    
    QTextCursor cursor = ui->codeEditor->textCursor();
    cursor.movePosition(QTextCursor::Start);
    
    for (int i = 0; i < lines.size(); ++i) {
        cursor.movePosition(QTextCursor::Down, QTextCursor::MoveAnchor, i);
        cursor.movePosition(QTextCursor::StartOfLine, QTextCursor::MoveAnchor);
        cursor.movePosition(QTextCursor::EndOfLine, QTextCursor::KeepAnchor);
        
        QTextCharFormat format;
        if (i == currentInstructionIndex) {
            format.setBackground(Qt::yellow);
        } else {
            format.setBackground(Qt::white);
        }
        cursor.setCharFormat(format);
    }
}

void MainWindow::executeCurrentInstruction()
{
    if (currentInstructionIndex < instructionList.size()) {
        QString instruction = instructionList[currentInstructionIndex];
        cpu->executeInstruction(instruction);
        ui->outputTextEdit->append(QString("执行: %1").arg(instruction));
        
        // 更新显示
        updateRegistersDisplay();
        updateMemoryDisplay();
        updateCodeDisplay();
        
        // 移动到下一条指令
        if (!cpu->isHalted()) {
            currentInstructionIndex++;
        }
    }
}

void MainWindow::on_runButton_clicked()
{
    // 重置状态
    cpu->reset();
    currentInstructionIndex = 0;
    
    // 获取代码
    QString code = ui->codeEditor->toPlainText();
    instructionList = code.split('\n');
    
    // 清空输出
    ui->outputTextEdit->clear();
    
    // 执行所有指令
    while (currentInstructionIndex < instructionList.size() && !cpu->isHalted()) {
        executeCurrentInstruction();
    }
    
    if (cpu->isHalted()) {
        ui->outputTextEdit->append("程序已停止");
    } else {
        ui->outputTextEdit->append("程序执行完毕");
    }
}

void MainWindow::on_stepButton_clicked()
{
    if (currentInstructionIndex >= instructionList.size() || cpu->isHalted()) {
        // 如果是新的执行过程，重置状态
        if (cpu->isHalted()) {
            cpu->reset();
        }
        
        // 获取代码
        QString code = ui->codeEditor->toPlainText();
        instructionList = code.split('\n');
        currentInstructionIndex = 0;
        
        // 清空输出
        ui->outputTextEdit->clear();
    }
    
    if (currentInstructionIndex < instructionList.size()) {
        executeCurrentInstruction();
    } else {
        ui->outputTextEdit->append("程序已执行完毕");
    }
}

void MainWindow::on_resetButton_clicked()
{
    cpu->reset();
    currentInstructionIndex = 0;
    updateRegistersDisplay();
    updateMemoryDisplay();
    updateCodeDisplay();
    ui->outputTextEdit->clear();
    ui->outputTextEdit->append("系统已重置");
}

void MainWindow::on_interruptButton_clicked()
{
    bool ok;
    int interruptNumber = QInputDialog::getInt(this, "触发中断", "输入中断号:", 20, 0, 255, 1, &ok);
    
    if (ok) {
        cpu->triggerInterrupt(interruptNumber);
        ui->outputTextEdit->append(QString("手动触发中断 %1").arg(interruptNumber));
        updateRegistersDisplay();
    }
}

void MainWindow::on_loadExampleButton_clicked()
{
    loadExampleCode();
}

void MainWindow::loadExampleCode()
{
    QString exampleCode = "; 计算斐波那契数列\n"
                          "MOV AX, $10      ; 设置计算的斐波那契数的数量\n"
                          "MOV [200], AX    ; 保存到内存位置200\n"
                          "MOV AX, $0       ; 第一个斐波那契数\n"
                          "MOV BX, $1       ; 第二个斐波那契数\n"
                          "MOV [201], AX    ; 保存第一个数\n"
                          "MOV [202], BX    ; 保存第二个数\n"
                          "MOV CX, $2       ; 已经生成了2个数\n"
                          "\n"
                          "FIB_LOOP:\n"
                          "    CMP CX, [200] ; 检查是否生成了足够的数\n"
                          "    JGE FIB_END   ; 如果CX >= [200]，跳转到结束\n"
                          "    MOV DX, AX    ; 保存前一个数\n"
                          "    ADD AX, BX    ; 计算下一个数\n"
                          "    MOV BX, DX    ; BX现在是前一个数\n"
                          "    MOV SI, CX    ; 准备保存到内存\n"
                          "    ADD SI, $201  ; 计算内存地址\n"
                          "    MOV [SI], AX  ; 保存到内存\n"
                          "    INC CX        ; 增加计数器\n"
                          "    JMP FIB_LOOP  ; 继续循环\n"
                          "\n"
                          "FIB_END:\n"
                          "    MOV AX, $0    ; 返回值\n"
                          "    INT 21        ; 调用打印服务";
    
    ui->codeEditor->setPlainText(exampleCode);
}

void MainWindow::on_saveButton_clicked()
{
    QString fileName = QFileDialog::getSaveFileName(this, "保存文件", "", "汇编文件 (*.asm);;所有文件 (*)");
    
    if (!fileName.isEmpty()) {
        QFile file(fileName);
        if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {
            QTextStream out(&file);
            out << ui->codeEditor->toPlainText();
            file.close();
            ui->outputTextEdit->append(QString("文件已保存: %1").arg(fileName));
        } else {
            QMessageBox::warning(this, "保存失败", "无法打开文件进行写入");
        }
    }
}

void MainWindow::on_loadButton_clicked()
{
    QString fileName = QFileDialog::getOpenFileName(this, "打开文件", "", "汇编文件 (*.asm);;所有文件 (*)");
    
    if (!fileName.isEmpty()) {
        QFile file(fileName);
        if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
            QTextStream in(&file);
            ui->codeEditor->setPlainText(in.readAll());
            file.close();
            ui->outputTextEdit->append(QString("文件已加载: %1").arg(fileName));
        } else {
            QMessageBox::warning(this, "加载失败", "无法打开文件进行读取");
        }
    }
}    